/**
 * @file DRV_eeprom.h
 * @brief Software implementation of eeprom for 51 microcontroller.
 * @author David Xu & zhongziming
 * @version 1.0.0
 * @date 2023-11-27
 * @note none
 */

#ifndef _DRV_EEPROM_H_
#define _DRV_EEPROM_H_

#include "ct_type.h"
#include "drv_soft_i2c.h"
/*****************************************************************************
 * Select the actual EEPROM specifications to be used in practice
 ****************************************************************************/
// EEPROM specifications to be used in practice
#define EEPROM_24C01
// #define EEPROM_24C02
//  #define EEPROM_24C04
//  #define EEPROM_24C08
//  #define EEPROM_24C16
//  #define EEPROM_24C32
//  #define EEPROM_24C64
//  #define EEPROM_24C128
//  #define EEPROM_24C256

// Actual connection status of address pins
// 0 for pull-down, 1 for pull-up
#define EEPROM_A0 0
#define EEPROM_A1 0
#define EEPROM_A2 0

/*****************************************************************************
 * Define EEPROM parameters
 ****************************************************************************/

// The following section is for conditional compilation and does not need modification
#define EEPROM_ERROR   0
#define EEPROM_SUCCESS 1
#define EEPROM_CHIP_ID 0xA0 | (EEPROM_A2 << 3) | (EEPROM_A1 << 2) | (EEPROM_A0 << 1)

#ifdef EEPROM_24C01
#define EEPROM_MORE_REG_BITS    0            // How many bits of the register high address occupy the ID address
#define EEPROM_REG_BYTES        1            // How many bytes the register address occupies
#define EEPROM_PAGE_BYTES       8            // How many bytes per page
#define EEPROM_MAX_ADDRESS      (128 - 1)    // Highest readable and writable address
#define EEPROM_WRITE_CYCLE_TIME 5            // Internal data processing time of the chip
#endif

#ifdef EEPROM_24C02
#define EEPROM_MORE_REG_BITS    0
#define EEPROM_REG_BYTES        1
#define EEPROM_PAGE_BYTES       8
#define EEPROM_MAX_ADDRESS      (256 - 1)
#define EEPROM_WRITE_CYCLE_TIME 5
#endif

#ifdef EEPROM_24C04
#define EEPROM_MORE_REG_BITS    1
#define EEPROM_REG_BYTES        1
#define EEPROM_PAGE_BYTES       16
#define EEPROM_MAX_ADDRESS      (512 - 1)
#define EEPROM_WRITE_CYCLE_TIME 5
#endif

#ifdef EEPROM_24C08
#define EEPROM_MORE_REG_BITS    2
#define EEPROM_REG_BYTES        1
#define EEPROM_PAGE_BYTES       16
#define EEPROM_MAX_ADDRESS      (1024 - 1)
#define EEPROM_WRITE_CYCLE_TIME 5
#endif

#ifdef EEPROM_24C16
#define EEPROM_MORE_REG_BITS    3
#define EEPROM_REG_BYTES        1
#define EEPROM_PAGE_BYTES       16
#define EEPROM_MAX_ADDRESS      (2048 - 1)
#define EEPROM_WRITE_CYCLE_TIME 5
#endif

#ifdef EEPROM_24C32
#define EEPROM_MORE_REG_BITS    0
#define EEPROM_REG_BYTES        2
#define EEPROM_PAGE_BYTES       32
#define EEPROM_MAX_ADDRESS      (4096 - 1)
#define EEPROM_WRITE_CYCLE_TIME 10
#endif

#ifdef EEPROM_24C64
#define EEPROM_MORE_REG_BITS    0
#define EEPROM_REG_BYTES        2
#define EEPROM_PAGE_BYTES       32
#define EEPROM_MAX_ADDRESS      (8192 - 1)
#define EEPROM_WRITE_CYCLE_TIME 10
#endif

#ifdef EEPROM_24C128
#define EEPROM_MORE_REG_BITS    0
#define EEPROM_REG_BYTES        2
#define EEPROM_PAGE_BYTES       64
#define EEPROM_MAX_ADDRESS      (16384 - 1)
#define EEPROM_WRITE_CYCLE_TIME 10
#endif

#ifdef EEPROM_24C256
#define EEPROM_MORE_REG_BITS    0
#define EEPROM_REG_BYTES        2
#define EEPROM_PAGE_BYTES       64
#define EEPROM_MAX_ADDRESS      (32768 - 1)
#define EEPROM_WRITE_CYCLE_TIME 10
#endif

uint8_t EepromWrite(uint16_t memory_address, uint8_t *dat, uint16_t length);
uint8_t EepromRead(uint16_t memory_address, uint8_t *dat, uint16_t length);
#endif